home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / LIB / GLE / SEGMENT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  11.9 KB  |  424 lines

  1.  
  2. /*
  3.  * MODULE NAME: segment.c
  4.  *
  5.  * FUNCTION:
  6.  * This module contains code that draws cylinder sections.  There are a
  7.  * number of different segment routines presented: with and without colors,
  8.  * with and without normals, with and without front and back normals.
  9.  *
  10.  * HISTORY:
  11.  * written by Linas Vepstas August/September 1991
  12.  * split into multiple compile units, Linas, October 1991
  13.  * added normal vectors Linas, October 1991
  14.  * consoldated from other modules,  Linas Vepstas, March 1993
  15.  */
  16.  
  17. #include <malloc.h>
  18. #include <stdlib.h>
  19. #include <math.h>
  20. #include <string.h>    /* for the memcpy() subroutine */
  21. #include "port.h"
  22. #include "GL/tube.h"
  23. #include "extrude.h"
  24. #include "tube_gc.h"
  25. #include "segment.h"
  26.  
  27.  
  28. /* ============================================================ */
  29.  
  30. void draw_segment_plain (int ncp,    /* number of contour points */
  31.                          gleDouble front_contour[][3],    
  32.                          gleDouble back_contour[][3],
  33.                          int inext, double len)
  34. {
  35.    int j;
  36.  
  37.    /* draw the tube segment */
  38.    BGNTMESH (inext, len);
  39.    for (j=0; j<ncp; j++) {
  40.       V3F (front_contour[j], j, FRONT);
  41.       V3F (back_contour[j], j, BACK);
  42.    }
  43.  
  44.    if (__TUBE_CLOSE_CONTOUR) {
  45.       /* connect back up to first point of contour */
  46.       V3F (front_contour[0], 0, FRONT);
  47.       V3F (back_contour[0], 0, BACK);
  48.    }
  49.    ENDTMESH ();
  50. }
  51.  
  52. /* ============================================================ */
  53.  
  54. void draw_segment_color (int ncp,    /* number of contour points */
  55.                          gleDouble front_contour[][3],    
  56.                          gleDouble back_contour[][3],    
  57.                          float color_last[3],
  58.                          float color_next[3],
  59.                          int inext, double len)
  60. {
  61.    int j;
  62.  
  63.    /* draw the tube segment */
  64.    BGNTMESH (inext, len);
  65.    for (j=0; j<ncp; j++) {
  66.       C3F (color_last);
  67.       V3F (front_contour[j], j, FRONT);
  68.  
  69.       C3F (color_next);
  70.       V3F (back_contour[j], j, BACK);
  71.    }
  72.  
  73.    if (__TUBE_CLOSE_CONTOUR) {
  74.       /* connect back up to first point of contour */
  75.       C3F (color_last);
  76.       V3F (front_contour[0], 0, FRONT);
  77.  
  78.       C3F (color_next);
  79.       V3F (back_contour[0], 0, BACK);
  80.    }
  81.  
  82.    ENDTMESH ();
  83. }
  84.  
  85. /* ============================================================ */
  86.  
  87. void draw_segment_edge_n (int ncp,    /* number of contour points */
  88.                            gleDouble front_contour[][3],    
  89.                            gleDouble back_contour[][3],    
  90.                            double norm_cont[][3],
  91.                            int inext, double len)
  92. {
  93.    int j;
  94.  
  95.    /* draw the tube segment */
  96.    BGNTMESH (inext,len);
  97.    for (j=0; j<ncp; j++) {
  98.       N3F_D (norm_cont[j]);
  99.       V3F (front_contour[j], j, FRONT);
  100.       V3F (back_contour[j], j, BACK);
  101.    }
  102.  
  103.    if (__TUBE_CLOSE_CONTOUR) {
  104.       /* connect back up to first point of contour */
  105.       N3F_D (norm_cont[0]);
  106.       V3F (front_contour[0], 0, FRONT);
  107.       V3F (back_contour[0], 0, BACK);
  108.    }
  109.    ENDTMESH ();
  110. }
  111.  
  112. /* ============================================================ */
  113.  
  114. void draw_segment_c_and_edge_n (int ncp,    /* number of contour points */
  115.                            gleDouble front_contour[][3],    
  116.                            gleDouble back_contour[][3],    
  117.                            double norm_cont[][3],
  118.                            float color_last[3],
  119.                            float color_next[3],
  120.                            int inext, double len)
  121. {
  122.    int j;
  123.  
  124.    /* draw the tube segment */
  125.    BGNTMESH (inext, len);
  126.    for (j=0; j<ncp; j++) {
  127.       C3F (color_last);
  128.       N3F_D (norm_cont[j]);
  129.       V3F (front_contour[j], j, FRONT);
  130.  
  131.       C3F (color_next);
  132.       N3F_D (norm_cont[j]);
  133.       V3F (back_contour[j], j, BACK);
  134.    }
  135.  
  136.    if (__TUBE_CLOSE_CONTOUR) {
  137.       /* connect back up to first point of contour */
  138.       C3F (color_last);
  139.       N3F_D (norm_cont[0]);
  140.       V3F (front_contour[0], 0, FRONT);
  141.    
  142.       C3F (color_next);
  143.       N3F_D (norm_cont[0]);
  144.       V3F (back_contour[0], 0, BACK);
  145.    }
  146.    ENDTMESH ();
  147. }
  148.  
  149. /* ============================================================ */
  150.  
  151. void draw_segment_facet_n (int ncp,    /* number of contour points */
  152.                            gleDouble front_contour[][3],    
  153.                            gleDouble back_contour[][3],    
  154.                            double norm_cont[][3],
  155.                            int inext, double len)
  156. {
  157.    int j;
  158.  
  159.    /* draw the tube segment */
  160.    BGNTMESH (inext, len);
  161.    for (j=0; j<ncp-1; j++) {
  162.       N3F_D (norm_cont[j]);
  163.       V3F (front_contour[j], j, FRONT);
  164.       V3F (back_contour[j], j, BACK);
  165.       V3F (front_contour[j+1], j+1, FRONT);
  166.       V3F (back_contour[j+1], j+1, BACK);
  167.    }
  168.  
  169.    if (__TUBE_CLOSE_CONTOUR) {
  170.       /* connect back up to first point of contour */
  171.       N3F_D (norm_cont[ncp-1]);
  172.       V3F (front_contour[ncp-1], ncp-1, FRONT);
  173.       V3F (back_contour[ncp-1], ncp-1, BACK);
  174.       V3F (front_contour[0], 0, FRONT);
  175.       V3F (back_contour[0], 0, BACK);
  176.    }
  177.  
  178.    ENDTMESH ();
  179. }
  180.  
  181. /* ============================================================ */
  182.  
  183. void draw_segment_c_and_facet_n (int ncp,    /* number of contour points */
  184.                            gleDouble front_contour[][3],    
  185.                            gleDouble back_contour[][3],    
  186.                            double norm_cont[][3],
  187.                            float color_last[3],
  188.                            float color_next[3],
  189.                            int inext, double len)
  190. {
  191.    int j;
  192.    /* Note about this code:
  193.     * At first, when looking at this code, it appears to be really dumb:
  194.     * the N3F() call appears to be repeated multiple times, for no
  195.     * apparent purpose.  It would seem that a performance improvement
  196.     * would be gained by stripping it out. !DONT DO IT!
  197.     * When there are no local lights or viewers, the V3F() subroutine
  198.     * does not trigger a recalculation of the lighting equations.
  199.     * However, we MUST trigger lighting, since otherwise colors come out
  200.     * wrong.  Trigger lighting by doing an N3F call.
  201.     */
  202.  
  203.    /* draw the tube segment */
  204.    BGNTMESH (inext, len);
  205.    for (j=0; j<ncp-1; j++) {
  206.       C3F (color_last);
  207.       N3F_D (norm_cont[j]);
  208.       V3F (front_contour[j], j, FRONT);
  209.  
  210.       C3F (color_next);
  211.       N3F_D (norm_cont[j]);
  212.       V3F (back_contour[j], j, BACK);
  213.  
  214.       C3F (color_last);
  215.       N3F_D (norm_cont[j]);
  216.       V3F (front_contour[j+1], j+1, FRONT);
  217.  
  218.       C3F (color_next);
  219.       N3F_D (norm_cont[j]);
  220.       V3F (back_contour[j+1], j+1, BACK);
  221.    }
  222.  
  223.    if (__TUBE_CLOSE_CONTOUR) {
  224.       /* connect back up to first point of contour */
  225.       C3F (color_last);
  226.       N3F_D (norm_cont[ncp-1]);
  227.       V3F (front_contour[ncp-1], ncp-1, FRONT);
  228.    
  229.       C3F (color_next);
  230.       N3F_D (norm_cont[ncp-1]);
  231.       V3F (back_contour[ncp-1], ncp-1, BACK);
  232.    
  233.       C3F (color_last);
  234.       N3F_D (norm_cont[ncp-1]);
  235.       V3F (front_contour[0], 0, FRONT);
  236.    
  237.       C3F (color_next);
  238.       N3F_D (norm_cont[ncp-1]);
  239.       V3F (back_contour[0], 0, BACK);
  240.    }
  241.  
  242.    ENDTMESH ();
  243. }
  244.  
  245. /* ============================================================ */
  246. /* ============================================================ */
  247. /* 
  248.  * This routine draws a segment with normals specified at each end.
  249.  */
  250.  
  251. void draw_binorm_segment_edge_n (int ncp,      /* number of contour points */
  252.                            double front_contour[][3],
  253.                            double back_contour[][3],
  254.                            double front_norm[][3],
  255.                            double back_norm[][3],
  256.                            int inext, double len)
  257. {
  258.    int j;
  259.  
  260.    /* draw the tube segment */
  261.    BGNTMESH (inext, len);
  262.    for (j=0; j<ncp; j++) {
  263.       N3F_D (front_norm[j]);
  264.       V3F_D (front_contour[j], j, FRONT);
  265.       N3F_D (back_norm[j]);
  266.       V3F_D (back_contour[j], j, BACK);
  267.    }
  268.  
  269.    if (__TUBE_CLOSE_CONTOUR) {
  270.       /* connect back up to first point of contour */
  271.       N3F_D (front_norm[0]);
  272.       V3F_D (front_contour[0], 0, FRONT);
  273.       N3F_D (back_norm[0]);
  274.       V3F_D (back_contour[0], 0, BACK);
  275.    }
  276.    ENDTMESH ();
  277.  
  278. }
  279.  
  280. /* ============================================================ */
  281.  
  282. void draw_binorm_segment_c_and_edge_n (int ncp,    /* number of contour points */
  283.                            double front_contour[][3],    
  284.                            double back_contour[][3],    
  285.                            double front_norm[][3],
  286.                            double back_norm[][3],
  287.                            float color_last[3],
  288.                            float color_next[3],
  289.                            int inext, double len)
  290. {
  291.    int j;
  292.  
  293.    /* draw the tube segment */
  294.    BGNTMESH (inext, len);
  295.    for (j=0; j<ncp; j++) {
  296.       C3F (color_last);
  297.       N3F_D (front_norm[j]);
  298.       V3F_D (front_contour[j], j, FRONT);
  299.  
  300.       C3F (color_next);
  301.       N3F_D (back_norm[j]);
  302.       V3F_D (back_contour[j], j, BACK);
  303.    }
  304.  
  305.    if (__TUBE_CLOSE_CONTOUR) {
  306.       /* connect back up to first point of contour */
  307.       C3F (color_last);
  308.       N3F_D (front_norm[0]);
  309.       V3F_D (front_contour[0], 0, FRONT);
  310.    
  311.       C3F (color_next);
  312.       N3F_D (back_norm[0]);
  313.       V3F_D (back_contour[0], 0, BACK);
  314.    }
  315.    ENDTMESH ();
  316. }
  317.  
  318. /* ============================================================ */
  319. /* 
  320.  * This routine draws a piece of the round segment with psuedo-facet
  321.  * normals.  I say "psuedo-facet" because the resulting object looks 
  322.  * much, much better than real facet normals, and is what the  round
  323.  * join style was meant to accomplish for face normals.   
  324.  */
  325.  
  326. void draw_binorm_segment_facet_n (int ncp,      /* number of contour points */
  327.                            double front_contour[][3],
  328.                            double back_contour[][3],
  329.                            double front_norm[][3],
  330.                            double back_norm[][3],
  331.                            int inext, double len)
  332. {
  333.    int j;
  334.  
  335.    /* draw the tube segment */
  336.    BGNTMESH (inext, len);
  337.    for (j=0; j<ncp-1; j++) {
  338.       N3F_D (front_norm[j]);
  339.       V3F_D (front_contour[j], j, FRONT);
  340.  
  341.       N3F_D (back_norm[j]);
  342.       V3F_D (back_contour[j], j, BACK);
  343.  
  344.       N3F_D (front_norm[j]);
  345.       V3F_D (front_contour[j+1], j+1, FRONT);
  346.  
  347.       N3F_D (back_norm[j]);
  348.       V3F_D (back_contour[j+1], j+1, BACK);
  349.    }
  350.  
  351.    if (__TUBE_CLOSE_CONTOUR) {
  352.       /* connect back up to first point of contour */
  353.       N3F_D (front_norm[ncp-1]);
  354.       V3F_D (front_contour[ncp-1], ncp-1, FRONT);
  355.  
  356.       N3F_D (back_norm[ncp-1]);
  357.       V3F_D (back_contour[ncp-1], ncp-1, BACK);
  358.  
  359.       N3F_D (front_norm[ncp-1]);
  360.       V3F_D (front_contour[0], 0, FRONT);
  361.  
  362.       N3F_D (back_norm[ncp-1]);
  363.       V3F_D (back_contour[0], 0, BACK);
  364.    }
  365.    ENDTMESH ();
  366. }
  367.  
  368. /* ============================================================ */
  369.  
  370. void draw_binorm_segment_c_and_facet_n (int ncp,
  371.                            double front_contour[][3],    
  372.                            double back_contour[][3],    
  373.                            double front_norm[][3],
  374.                            double back_norm[][3],
  375.                            float color_last[3],
  376.                            float color_next[3],
  377.                            int inext, double len)
  378. {
  379.    int j;
  380.  
  381.    /* draw the tube segment */
  382.    BGNTMESH (inext, len);
  383.    for (j=0; j<ncp-1; j++) {
  384.       C3F (color_last);
  385.       N3F_D (front_norm[j]);
  386.       V3F_D (front_contour[j], j, FRONT);
  387.  
  388.       C3F (color_next);
  389.       N3F_D (back_norm[j]);
  390.       V3F_D (back_contour[j], j, BACK);
  391.  
  392.       C3F (color_last);
  393.       N3F_D (front_norm[j]);
  394.       V3F_D (front_contour[j+1], j+1, FRONT);
  395.  
  396.       C3F (color_next);
  397.       N3F_D (back_norm[j]);
  398.       V3F_D (back_contour[j+1], j+1, BACK);
  399.    }
  400.  
  401.    if (__TUBE_CLOSE_CONTOUR) {
  402.       /* connect back up to first point of contour */
  403.       C3F (color_last);
  404.       N3F_D (front_norm[ncp-1]);
  405.       V3F_D (front_contour[ncp-1], ncp-1, FRONT);
  406.    
  407.       C3F (color_next);
  408.       N3F_D (back_norm[ncp-1]);
  409.       V3F_D (back_contour[ncp-1], ncp-1, BACK);
  410.    
  411.       C3F (color_last);
  412.       N3F_D (front_norm[ncp-1]);
  413.       V3F_D (front_contour[0], 0, FRONT);
  414.    
  415.       C3F (color_next);
  416.       N3F_D (back_norm[ncp-1]);
  417.       V3F_D (back_contour[0], 0, BACK);
  418.    }
  419.  
  420.    ENDTMESH ();
  421. }
  422.  
  423. /* ==================== END OF FILE =========================== */
  424.